#include "decider_base/dependence/common_macro.h"

#define ROSSUB(type_name, msg_name, topic_name, time_out_frame)                                                              \
    type_name       msg_name##_;                                                                                             \
    ros::Subscriber sub_##msg_name##_ = nh_.subscribe<type_name>(topic_name, 1, &MessageHandler::callback_##msg_name, this); \
    int             msg_name##_msgs_disconnected_times_ = 100000;                                                            \
    inline bool     msg_name##_msgs_on_connecting() { return msg_name##_msgs_disconnected_times_ < time_out_frame; }         \
    inline void     callback_##msg_name(const type_name::ConstPtr& msg) {                                                    \
        msg_name##_                         = *msg;                                                                      \
        msg_name##_msgs_disconnected_times_ = 0;                                                                         \
    }
#define ROSPUB(type_name, msg_name, topic_name) \
    type_name      msg_name##_;                 \
    ros::Publisher pub_##msg_name##_ = nh_.advertise<type_name>(topic_name, 1);

#define MSGPUBSTATEMENT_1(_1) pub_##_1##_.publish(_1##_);

#define MSGPUBSTATEMENT_2(_1, _2) \
    MSGPUBSTATEMENT_1(_1)         \
    MSGPUBSTATEMENT_1(_2)

#define MSGPUBSTATEMENT_3(_1, _2, _3) \
    MSGPUBSTATEMENT_1(_1)             \
    MSGPUBSTATEMENT_2(_2, _3)

#define MSGPUBSTATEMENT_4(_1, _2, _3, _4) \
    MSGPUBSTATEMENT_1(_1)                 \
    MSGPUBSTATEMENT_3(_2, _3, _4)

#define MSGPUBSTATEMENT_5(_1, _2, _3, _4, _5) \
    MSGPUBSTATEMENT_1(_1)                     \
    MSGPUBSTATEMENT_4(_2, _3, _4, _5)

#define MSGPUBSTATEMENT_6(_1, _2, _3, _4, _5, _6) \
    MSGPUBSTATEMENT_1(_1)                         \
    MSGPUBSTATEMENT_5(_2, _3, _4, _5, _6)

#define MSGPUBSTATEMENT_7(_1, _2, _3, _4, _5, _6, _7) \
    MSGPUBSTATEMENT_1(_1)                             \
    MSGPUBSTATEMENT_6(_2, _3, _4, _5, _6, _7)

#define MSGPUBSTATEMENT_8(_1, _2, _3, _4, _5, _6, _7, _8) \
    MSGPUBSTATEMENT_1(_1)                                 \
    MSGPUBSTATEMENT_7(_2, _3, _4, _5, _6, _7, _8)

#define MSGPUBSTATEMENT_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) \
    MSGPUBSTATEMENT_1(_1)                                     \
    MSGPUBSTATEMENT_8(_2, _3, _4, _5, _6, _7, _8, _9)

#define MSGPUBSTATEMENT_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
    MSGPUBSTATEMENT_1(_1)                                           \
    MSGPUBSTATEMENT_9(_2, _3, _4, _5, _6, _7, _8, _9, _10)

#define MSGPUBSTATEMENT(...) SYMBOL_CATENATE_WITH_MACRO(MSGPUBSTATEMENT_, COUNT_PARMS(__VA_ARGS__))(__VA_ARGS__)

#define MSGPUBFUNC(...) \
    inline void PublishOnce() { MSGPUBSTATEMENT(__VA_ARGS__) }

#define MSGTIMEPULSSTATEMENT_1(_1) ++_1##_msgs_disconnected_times_;

#define MSGTIMEPULSSTATEMENT_2(_1, _2) \
    MSGTIMEPULSSTATEMENT_1(_1)         \
    MSGTIMEPULSSTATEMENT_1(_2)

#define MSGTIMEPULSSTATEMENT_3(_1, _2, _3) \
    MSGTIMEPULSSTATEMENT_1(_1)             \
    MSGTIMEPULSSTATEMENT_2(_2, _3)

#define MSGTIMEPULSSTATEMENT_4(_1, _2, _3, _4) \
    MSGTIMEPULSSTATEMENT_1(_1)                 \
    MSGTIMEPULSSTATEMENT_3(_2, _3, _4)

#define MSGTIMEPULSSTATEMENT_5(_1, _2, _3, _4, _5) \
    MSGTIMEPULSSTATEMENT_1(_1)                     \
    MSGTIMEPULSSTATEMENT_4(_2, _3, _4, _5)

#define MSGTIMEPULSSTATEMENT_6(_1, _2, _3, _4, _5, _6) \
    MSGTIMEPULSSTATEMENT_1(_1)                         \
    MSGTIMEPULSSTATEMENT_5(_2, _3, _4, _5, _6)

#define MSGTIMEPULSSTATEMENT_7(_1, _2, _3, _4, _5, _6, _7) \
    MSGTIMEPULSSTATEMENT_1(_1)                             \
    MSGTIMEPULSSTATEMENT_6(_2, _3, _4, _5, _6, _7)

#define MSGTIMEPULSSTATEMENT_8(_1, _2, _3, _4, _5, _6, _7, _8) \
    MSGTIMEPULSSTATEMENT_1(_1)                                 \
    MSGTIMEPULSSTATEMENT_7(_2, _3, _4, _5, _6, _7, _8)

#define MSGTIMEPULSSTATEMENT_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) \
    MSGTIMEPULSSTATEMENT_1(_1)                                     \
    MSGTIMEPULSSTATEMENT_8(_2, _3, _4, _5, _6, _7, _8, _9)

#define MSGTIMEPULSSTATEMENT_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
    MSGTIMEPULSSTATEMENT_1(_1)                                           \
    MSGTIMEPULSSTATEMENT_9(_2, _3, _4, _5, _6, _7, _8, _9, _10)

#define MSGTIMEPULSSTATEMENT(...) SYMBOL_CATENATE_WITH_MACRO(MSGTIMEPULSSTATEMENT_, COUNT_PARMS(__VA_ARGS__))(__VA_ARGS__)

#define MSGSHOWSTATEMENT_1(_1) << (_1##_msgs_on_connecting() ? " \033[1m\033[32m" : " \033[31m") << #_1 << "\033[0m "

#define MSGSHOWSTATEMENT_2(_1, _2) \
    MSGSHOWSTATEMENT_1(_1)         \
    MSGSHOWSTATEMENT_1(_2)

#define MSGSHOWSTATEMENT_3(_1, _2, _3) \
    MSGSHOWSTATEMENT_1(_1)             \
    MSGSHOWSTATEMENT_2(_2, _3)

#define MSGSHOWSTATEMENT_4(_1, _2, _3, _4) \
    MSGSHOWSTATEMENT_1(_1)                 \
    MSGSHOWSTATEMENT_3(_2, _3, _4)

#define MSGSHOWSTATEMENT_5(_1, _2, _3, _4, _5) \
    MSGSHOWSTATEMENT_1(_1)                     \
    MSGSHOWSTATEMENT_4(_2, _3, _4, _5)

#define MSGSHOWSTATEMENT_6(_1, _2, _3, _4, _5, _6) \
    MSGSHOWSTATEMENT_1(_1)                         \
    MSGSHOWSTATEMENT_5(_2, _3, _4, _5, _6)

#define MSGSHOWSTATEMENT_7(_1, _2, _3, _4, _5, _6, _7) \
    MSGSHOWSTATEMENT_1(_1)                             \
    MSGSHOWSTATEMENT_6(_2, _3, _4, _5, _6, _7)

#define MSGSHOWSTATEMENT_8(_1, _2, _3, _4, _5, _6, _7, _8) \
    MSGSHOWSTATEMENT_1(_1)                                 \
    MSGSHOWSTATEMENT_7(_2, _3, _4, _5, _6, _7, _8)

#define MSGSHOWSTATEMENT_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) \
    MSGSHOWSTATEMENT_1(_1)                                     \
    MSGSHOWSTATEMENT_8(_2, _3, _4, _5, _6, _7, _8, _9)

#define MSGSHOWSTATEMENT_10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
    MSGSHOWSTATEMENT_1(_1)                                           \
    MSGSHOWSTATEMENT_9(_2, _3, _4, _5, _6, _7, _8, _9, _10)

#define MSGSHOWSTATEMENT(...) SYMBOL_CATENATE_WITH_MACRO(MSGSHOWSTATEMENT_, COUNT_PARMS(__VA_ARGS__))(__VA_ARGS__)

#define MSGSUBFUNC(...)                                                                                 \
    inline void SubscrOnce() {                                                                          \
        MSGTIMEPULSSTATEMENT(__VA_ARGS__)                                                               \
        ros::spinOnce();                                                                                \
        std::cout << "M|-MessageHandler: subscrib status :" MSGSHOWSTATEMENT(__VA_ARGS__) << std::endl; \
    }
